﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using _5E.Infrastructure.Querying;
using _5E.Infrastructure.UnitOfWork;
using WholesaleOnline.Contract;
using WholesaleOnline.DataContract.Messaging;
using WholesaleOnline.Model;
using WholesaleOnline.Model.Repository;

namespace WholesaleOnline.Service.Services
{
    public class BasketService : IBasketService
    {
        private IProductRepository m_productRepository = null;
        private IBasketRepository m_basketRepository = null;
        private IBasketItemRepository m_basketItemRepository = null;
        private IUnitOfWork m_uow = null;

        public BasketService(
            IProductRepository productRepsitory,
            IBasketRepository basketRepository,
            IBasketItemRepository basketItemRepository,
            IUnitOfWork uow)
        {
            m_productRepository = productRepsitory;
            m_basketRepository = basketRepository;
            m_basketItemRepository = basketItemRepository;
            m_uow = uow;
        }

        public void AddBasketItem(AddBasketItemRequest requset)
        {
            WoBasket basket = GetBasketBy(requset.BuyerId, requset.SellerId);

            WoProduct product = m_productRepository.FindBy(requset.ProductId);
            basket.Add(product, requset.Qty);

            m_basketRepository.Save(basket);
            m_uow.Comit();
        }

        private WoBasket GetBasketBy(Guid buyerId, Guid sellerId)
        {
            Query query = new Query();
            query.Add<WoBasket>(b => b.BuyerId, CriteriaOperator.Eq, buyerId);
            query.Add<WoBasket>(b => b.SellerId, CriteriaOperator.Eq, sellerId);

            IEnumerable<WoBasket> baskets = m_basketRepository.FindBy(query);
            return 0 < baskets.Count() ? baskets.First() : CreateBasketBy(buyerId, sellerId);
        }

        private WoBasket CreateBasketBy(Guid buyerId, Guid sellerId)
        {
            WoBasket basket = BasketFactory.CeraetFrom(buyerId, sellerId);
            m_basketRepository.Add(basket);
            return basket;
        }

        public GetBasketsResponse GetBasketsBy(GetBasketsRequest request)
        {
            GetBasketsResponse response = new GetBasketsResponse();
            try
            {
                Query query = new Query();
                query.Add<WoBasket>(b => b.BuyerId, CriteriaOperator.Eq, request.BuyerId);
                response.Baskets = m_basketRepository.FindBy(query);
                response.Success = true;
                return response;
            }
            catch (Exception)
            {
            }
            return response;
        }

        public void UpdateBasketProductQtyBy(UpdateBasketProductQtyRequest request)
        {
            try
            {
                WoBasketItem item = m_basketItemRepository.FindBy(request.ItemId);
                WoBasket basket = item.Basket;
                basket.ChangeQtyBy(item.Product, request.Qty);

                m_basketRepository.Save(basket);
                m_uow.Comit();
            }
            catch (Exception)
            {
            }
        }

        public void RemoveBasketItemBy(RemoveBasketItemRequest request)
        {
            try
            {
                WoBasketItem item = m_basketItemRepository.FindBy(request.ItemId);
                WoBasket basket = item.Basket;
                basket.Remove(item.Product);

                m_basketRepository.Save(basket);
                m_uow.Comit();
            }
            catch (Exception)
            {
            }
        }
    }
}
